package com.plian.system.service.im.impl;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.BigDecimalUtil;
import com.plian.Tools.CollectionUtil;
import com.plian.system.bean.im.InvestmentDebtExcelBean;
import com.plian.system.entity.im.InvestmentDebt;
import com.plian.system.mapper.im.InvestmentDebtMapper;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.service.im.IInvestmentDebtService;
import com.plian.system.vo.im.InvestmentDebtVO;
import com.plian.system.wrapper.im.InvestmentDebtWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class InvestmentDebtServiceImpl extends BaseServiceImpl<InvestmentDebtMapper, InvestmentDebt> implements IInvestmentDebtService {


	private InvestmentDebtWrapper investmentDebtWrapper;

	@Override
	public boolean saveOrUpdate(InvestmentDebt investmentDebt) {
		return super.saveOrUpdate(investmentDebt);
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean deleteLogic(List<Long> ids) {
		for (Long id : ids) {
			InvestmentDebt investmentDebt = getById(id);
			if (investmentDebt == null) {
				return false;
			}
		}
		return super.deleteLogic(ids);
	}

	@Override
	public void write(List<InvestmentDebt> investmentDebts, ExcelWriter excelWriter, WriteSheet writeSheet, FillConfig fillConfig) {
		InvestmentDebtExcelBean total = InvestmentDebtExcelBean.builder().projectTotal(0).oneNumber(0).twoNumber(0).threeNumber(0).build();
		Map<Integer, List<InvestmentDebtVO>> map = investmentDebtWrapper.entityToVO(investmentDebts)
				.stream().collect(Collectors.groupingBy(InvestmentDebtVO::getProjectCategory));

		for (int i = 1, k = 2; i <= 2; i++, k--) {
			List<InvestmentDebtVO> list = map.get(i);
			InvestmentDebtExcelBean sum = InvestmentDebtExcelBean.builder().projectTotal(0).oneNumber(0).twoNumber(0).threeNumber(0).build();
			if (CollectionUtil.isNotEmpty(list)) {
				int index = 1;
				for (InvestmentDebtVO vo : list) {
					vo.setIndex(k + "." + index);
					index++;
					if (Optional.ofNullable(vo.getConstructionStatus()).isPresent()){
						switch (vo.getConstructionStatus()) {
							case 1:
								vo.setOneNumber(1);
								sum.setOneNumber(sum.getOneNumber() + 1);
								break;
							case 2:
								vo.setTwoNumber(1);
								sum.setTwoNumber(sum.getTwoNumber() + 1);
								break;
							case 3:
								vo.setThreeNumber(1);
								sum.setThreeNumber(sum.getThreeNumber() + 1);
								break;
							default:
								break;
						}
					}

					/**
					 * 小计
					 */
					sum.setProjectTotal(sum.getProjectTotal() + 1);
					sum.setPlanTotalInvestment(BigDecimalUtil.add(sum.getPlanTotalInvestment(), vo.getPlanTotalInvestment()));
					sum.setFiscalFunds(BigDecimalUtil.add(sum.getFiscalFunds(), vo.getFiscalFunds()));
					sum.setShareholderCapital(BigDecimalUtil.add(sum.getShareholderCapital(), vo.getShareholderCapital()));
					sum.setProjectLoan(	BigDecimalUtil.add(sum.getProjectLoan(), vo.getProjectLoan()));
					sum.setCompletedProjectsAccounts(BigDecimalUtil.add(sum.getCompletedProjectsAccounts(), vo.getCompletedProjectsAccounts()));
					sum.setActualFinancialExpenditure(BigDecimalUtil.add(sum.getActualFinancialExpenditure(), vo.getActualFinancialExpenditure()));
					sum.setActualFiscalFunds(BigDecimalUtil.add(sum.getActualFiscalFunds(), vo.getActualFiscalFunds()));
					sum.setActualShareholderCapital(BigDecimalUtil.add(sum.getActualShareholderCapital(), vo.getActualShareholderCapital()));
					sum.setDebtCapitalTotal(BigDecimalUtil.add(sum.getDebtCapitalTotal(), vo.getDebtCapitalTotal()));
					sum.setDebtCapitalLoan(BigDecimalUtil.add(sum.getDebtCapitalLoan(), vo.getDebtCapitalLoan()));
					sum.setDebtCapitalShareholderAdvance(BigDecimalUtil.add(sum.getDebtCapitalShareholderAdvance(), vo.getDebtCapitalShareholderAdvance()));
					sum.setFutureRaiseDebtAmount(BigDecimalUtil.add(sum.getFutureRaiseDebtAmount(), vo.getFutureRaiseDebtAmount()));
				}
				/**
				 * 数据填充
				 */
				switch (i) {
					case 1:
						excelWriter.fill(toMap("three", sum), fillConfig, writeSheet);
						excelWriter.fill(new FillWrapper("two", list), fillConfig, writeSheet);
						break;
					case 2:
						excelWriter.fill(toMap("two", sum), fillConfig, writeSheet);
						excelWriter.fill(new FillWrapper("one", list), fillConfig, writeSheet);
						break;
					default:
						break;

				}
			}

			/**
			 * 总计
			 */
			total.setProjectTotal(total.getProjectTotal() + sum.getProjectTotal());
			total.setOneNumber(total.getOneNumber() + sum.getOneNumber());
			total.setTwoNumber(total.getTwoNumber() + sum.getTwoNumber());
			total.setThreeNumber(total.getThreeNumber() + sum.getThreeNumber());
			total.setPlanTotalInvestment(BigDecimalUtil.add(total.getPlanTotalInvestment(), sum.getPlanTotalInvestment()));
			total.setFiscalFunds(BigDecimalUtil.add(total.getFiscalFunds(), sum.getFiscalFunds()));
			total.setShareholderCapital(BigDecimalUtil.add(total.getShareholderCapital(), sum.getShareholderCapital()));
			total.setProjectLoan(BigDecimalUtil.add(total.getProjectLoan(), sum.getProjectLoan()));
			total.setCompletedProjectsAccounts(BigDecimalUtil.add(total.getCompletedProjectsAccounts(), sum.getCompletedProjectsAccounts()));
			total.setActualFinancialExpenditure(BigDecimalUtil.add(total.getActualFinancialExpenditure(), sum.getActualFinancialExpenditure()));
			total.setActualFiscalFunds(BigDecimalUtil.add(total.getActualFiscalFunds(), sum.getActualFiscalFunds()));
			total.setActualShareholderCapital(BigDecimalUtil.add(total.getActualShareholderCapital(), sum.getActualShareholderCapital()));
			total.setDebtCapitalTotal(BigDecimalUtil.add(total.getDebtCapitalTotal(), sum.getDebtCapitalTotal()));
			total.setDebtCapitalLoan(BigDecimalUtil.add(total.getDebtCapitalLoan(), sum.getDebtCapitalLoan()));
			total.setDebtCapitalShareholderAdvance(BigDecimalUtil.add(total.getDebtCapitalShareholderAdvance(), sum.getDebtCapitalShareholderAdvance()));
			total.setFutureRaiseDebtAmount(BigDecimalUtil.add(total.getFutureRaiseDebtAmount(), sum.getFutureRaiseDebtAmount()));

		}
		excelWriter.fill(toMap("one", total), fillConfig, writeSheet);
	}

	@Override
	public boolean deleteByParentId(List<Long> ids) {
		LambdaQueryWrapper<InvestmentDebt> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(InvestmentDebt::getBaseInvestmentDebtId, ids);
		List<InvestmentDebt> investmentDebts = list(queryWrapper);
		if (CollectionUtil.isNotEmpty(investmentDebts)){
			return deleteLogic(investmentDebts.stream().map(InvestmentDebt::getId).collect(Collectors.toList()));
		}
		return true;
	}

    @Override
    public boolean deleteByBaseId(Long baseInvestmentDebtId) {
		List<InvestmentDebt> investmentDebts = list(new LambdaQueryWrapper<InvestmentDebt>().eq(InvestmentDebt::getBaseInvestmentDebtId, baseInvestmentDebtId));
		if (CollectionUtil.isNotEmpty(investmentDebts)){
			return deleteLogic(investmentDebts.stream().map(InvestmentDebt::getId).collect(Collectors.toList()));
		}
		return true;
    }


    private Map<String, Object> toMap(String str, InvestmentDebtExcelBean bean){
		Map<String, Object> map = new HashMap<>(16);
		map.put(str + "ProjectTotal", bean.getProjectTotal());
		map.put(str + "OneNumber", bean.getOneNumber());
		map.put(str + "TwoNumber", bean.getTwoNumber());
		map.put(str + "ThreeNumber", bean.getThreeNumber());
		map.put(str + "PlanTotalInvestment", bean.getPlanTotalInvestment());
		map.put(str + "FiscalFunds", bean.getFiscalFunds());
		map.put(str + "ShareholderCapital", bean.getShareholderCapital());
		map.put(str + "ProjectLoan", bean.getProjectLoan());
		map.put(str + "CompletedProjectsAccounts", bean.getCompletedProjectsAccounts());
		map.put(str + "ActualFinancialExpenditure", bean.getActualFinancialExpenditure());
		map.put(str + "ActualFiscalFunds", bean.getActualFiscalFunds());
		map.put(str + "ActualShareholderCapital", bean.getActualShareholderCapital());
		map.put(str + "DebtCapitalTotal", bean.getDebtCapitalTotal());
		map.put(str + "DebtCapitalLoan", bean.getDebtCapitalLoan());
		map.put(str + "DebtCapitalShareholderAdvance", bean.getDebtCapitalShareholderAdvance());
		map.put(str + "FutureRaiseDebtAmount", bean.getFutureRaiseDebtAmount());
		return map;

	}
}
